import logging

from sim_world import SimWorld
from task import Task
from composite_task import CompositeTask

class SimWorldWrapper(SimWorld):
    def __init__(self, **arg):
        super().__init__('config.ini', **arg)
        self.initLogger()
        self._num_steps = 36000
        self._tcs = self.getTCS()
        
    def initLogger(self):
        # create logger
        self._logger = logging.getLogger('MyTCS.SimWorldWrapper')
        
    def addRandomTasks(self, num):
        """
        产生一个随机任务，该任务的起始节点和目的节点都是随机产生的。
        :return: 所产生的任务。
        """
        print('hello')
        leaf_nodes = self._map.getLeafNodes()
        src = None
        dst = np.random.choice(leaf_nodes, size=num, replace=True)
        due = self._num_steps * self._step / 10
        delay = np.random.random_sample(size=num) * self._num_steps    
        for i in range(num):
            ctask = CompositeTask()
            ctask.add(Task(delay[i], due, src, dst[i], priority=0))
            #print('task from {0} to {1} with delay {2} generated'.format(src, dst[i], delay[i]))
            self._tcs.addCompositeTask(ctask, delay=delay[i])

    def step(self, src, dst):
        # 把“发起一个从src到dst的任务”作为一个动作。src/dst都必须是叶子节点，或者None
        # 当src为None，dst不为None时，相当于发起一个要求机器人到dst的任务，不论机器人当前的位置。
        # 当src不为None，dst为None时，相当于发起一个要求机器人到src的任务，不论机器人当前的位置。
        # 当src，dst均为None时，不发起任何任务。
        # 当src，dst均不为None时，发起一个要求机器人先到src，再到dst的任务。
        ctask = CompositeTask()
        if (src is None) and (dst is not None):
            ctask.add(Task(self.getTimer().getTime(), 60, None, dst, priority=0, creator='system'))
            self._logger.info('Time={0:.2f} wrapper create task ({1}, {2})'.format(self.getTimer().getTime(), None, dst))
        elif (dst is None) and (src is not None):
            ctask.add(Task(self.getTimer().getTime(), 60, None, src, priority=0, creator='system'))
            self._logger.info('Time={0:.2f} wrapper create task ({1}, {2})'.format(self.getTimer().getTime(), None, src))
        elif (src is not None) and (dst is not None):
            ctask.add(Task(self.getTimer().getTime(), 60, src, dst, priority=0, creator='system'))
            self._logger.info('Time={0:.2f} wrapper create task ({1}, {2})'.format(self.getTimer().getTime(), src, dst))
        
        if not ctask.isEmpty():
            self._tcs.addCompositeTask(ctask, delay=0)
        done = super().step()
        state = self._tcs.getScheduler().getTimeWindow()
        reward = -1.0*self._tcs.avgResponseTime(task_creator='user')
        return state, reward, done